#! /usr/bin/env python2  
# encoding=utf-8
import sys
reload(sys) 
sys.setdefaultencoding('utf8')
import os
ScriptPath = os.path.split( os.path.realpath( sys.argv[0] ) )[0]
import xmlrpclib
import ConfigParser
import datetime

# 每月2号执行，计算风险评测评分

config = ConfigParser.RawConfigParser()
config.read(ScriptPath+'/sys.cfg')
url = config.get('odoo','host')
uid = 1
pwd = config.get('odoo','password')
db = config.get('odoo','db')
models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

def last_month(num=15):
    # 上个月15号
    if num=='last':
        return (datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-01'),'%Y-%m-%d')+datetime.timedelta(days = -1)).strftime('%Y-%m-%d')
    return (datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-01'),'%Y-%m-%d')+datetime.timedelta(days = -3)).strftime('%Y-%m-'+str(num))


def compute_score():
    """
    应该赋予code以意义：
    风险评测对象的code应该是对应风险评测对象的模型名
    评测类型的code应该对应具体评测对象的评分字段名：main_score
    """
    # 首先遍历评测对象
    for category in models.execute_kw(db,uid,pwd,'tyibs.risk.category','search_read',[[]],{'fields':['code']}):
        # 首先根据风险评测对象找到对应计算模型并
        compute_model = False
        field = False
        # 生产厂家
        if category['code']=='tyibs.risk.brand':
            compute_model = 'tyibs.base.lift.factory'
            field = 'factory_id'
        # 维保单位
        if category['code']=='tyibs.risk.maintenance.company':
            compute_model = 'tyibs.base.maintenance.company'
            field = 'maintenance_company_id'
        # 使用单位
        if category['code']=='tyibs.risk.use.company':
            compute_model = 'tyibs.base.lift.use.company'
            field = 'use_company_id'
        compute_category(category,compute_model,field)

def compute_category(category,compute_model,field):
    # 计算评分
    # 需要计算的厂家id
    factory_ids = [i['id'] for i in models.execute_kw(db,uid,pwd,compute_model,'search_read',[[]],{'fields':['id']}) ]
    # 防错：已经计算过的厂家id==>针对评测时间是上个月15号的：
    computed_factory_ids = [i[field][0] for i in models.execute_kw(db,uid,pwd,category['code'],'search_read',[[['name','=',str(last_month()[:7])]]],{'fields':[field]}) ]
    need_compute_factory_ids = [i for i in factory_ids if i not in computed_factory_ids]
    # 所有评测类型：==》针对该类型的厂家，有这么多字段需要计算
    sub_categorys = models.execute_kw(db,uid,pwd,'tyibs.risk.sub.category','search_read',[[['category_id','=',category['id']]]],{'fields':['code','weight','']})
    for sub_category in sub_categorys:
        # 针对该字段，有以下事件需要计算
        sub_category['event'] = models.execute_kw(db,uid,pwd,'tyibs.risk.event.score','search_read',[[['sub_category_id','=',sub_category['id']]]],{'fields':['code','score','is_double','event_category_id']})
    # sub_categorys 这个对象已经是缓存的本次循环计算所需要的事件类型了
    for factory_id in need_compute_factory_ids:
        up_fac_risk = {
            'risk_create_time':datetime.datetime.now().strftime('%Y-%m-%d'),
            'risk_date':last_month('15'),
            'name':last_month()[:7]
        }
        up_fac_risk[field] = factory_id # 对应单位字段及其ID
        # 综合评分
        all_num = 0
        for sub_c in sub_categorys:
            # 依据评测类型添加属性:扣的分数
            score_re = compute_field_score(factory_id,compute_model,sub_c['event'],field)
            score = 100-score_re
            score = 100 if score>100 else score
            score = 0 if score<0 else score
            up_fac_risk[sub_c['code']] = score
            # 同时根据权重累加综合评分
            all_num = all_num + score*sub_c['weight']
        # 计算附加分
        all_num = all_num - compute_addition_score(factory_id,field)
        # 调整
        all_num = 100 if all_num>100 else all_num
        all_num = 0 if all_num<0 else all_num
        up_fac_risk['complex_score'] = all_num
        # 创建事件
        print u"创建++++++++++++++++++++"
        print compute_model
        print factory_id
        models.execute_kw(db,uid,pwd,category['code'],'create',[up_fac_risk])


def compute_field_score(fac_id,fac_name,events,field):
    # 计算字段分
    score = 0
    for event_1 in events:
        all_events = models.execute_kw(db,uid,pwd,'tyibs.risk.event.line','search_read',[[
                [field,'=',fac_id],['date','>=',last_month('01')],['date','<=',last_month('last')],['event_category_id','=',event_1['event_category_id'][0]]
            ]],{'fields':['id']})
        e_score = len(all_events)*event_1['score']
        if event_1['is_double']:
            e_score=e_score*2
        score = score + e_score
    return score

def compute_addition_score(fac_id,field):
    # 计算附加分
    all_events = models.execute_kw(db,uid,pwd,'tyibs.risk.event.addition','search_read',[[
            [field,'=',fac_id],['date','>=',last_month('01')],['date','<=',last_month('last')]
        ]],{'fields':['addition_score']})
    score = 0
    for event_1 in all_events:
        score = score + event_1['addition_score']
    return score

def main():
    month_day = config.get('risk-event','month_day')
    if month_day == datetime.datetime.now().strftime('%d'):
        print u"开始计算风险评测评分"
        compute_score()
    

if __name__ == '__main__':
    main()